import type { Ref } from "vue";
import type { MenuEntityReq } from "@/api/types";
import type { UseBaseForm } from "@/composables";
import { computed } from "vue";
import { menuApi } from "@/api";
import { useBaseForm } from "@/composables";
import { apiCall } from "@/utils/http/apiCall";
import { onlySubmitData } from "@/utils/tools";

interface UseMenuForm extends UseBaseForm<MenuEntityReq> {
    /** 菜单类型 */
    menuType: Ref<Exclude<CustomizeRouteMeta["menuType"], undefined>>;
    /** 获取表单初始meta */
    getInitFormMeta: () => CustomizeRouteMeta;
    /** 获取表单初始数据 */
    getInitFormData: () => MenuEntityReq;
    /** 提交 */
    onSubmit: (isEdit: boolean, callback: (message: string) => void) => Promise<void>;
    /** 重置表单 */
    resetForm: () => void;
}

export function useMenuForm(): UseMenuForm {
    /** 获取表单初始meta */
    function getInitFormMeta(): CustomizeRouteMeta {
        // 路由过滤只会过滤meta中showLink为false的菜单, 其他的都不受影响
        return { title: "", showLink: true, menuType: "menu" } as const;
    }

    /** 获取表单初始数据 */
    const getInitFormData = (): MenuEntityReq => ({
        id: undefined,
        parentId: null,
        path: "",
        name: null,
        redirect: null,
        component: null,
        meta: getInitFormMeta(),
    });

    const { formRef, submitLoading, formData, resetForm } = useBaseForm(getInitFormData);

    /** 菜单类型 */
    const menuType = computed(() => formData.meta.menuType || "menu");

    /** 提交菜单 */
    function submitMenu(isEdit: boolean, callback: (message: string) => void): void {
        const payload = onlySubmitData(getInitFormData(), formData);
        apiCall(
            () => {
                return isEdit ? menuApi.updateMenu(payload) : menuApi.createMenu(payload);
            },
            (data, resp) => {
                callback(resp.message);
            },
            {
                onFinally: () => {
                    submitLoading.value = false;
                },
            },
        );
    }

    /** 提交按钮权限 */
    function submitPermission(isEdit: boolean, callback: (message: string) => void): void {
        const payload = {
            id: formData.id,
            menuId: formData.parentId,
            code: formData.meta.auth || "",
            name: formData.meta.title,
            rank: formData.meta.rank || null,
            remark: formData.meta.remark || null,
        };
        apiCall(
            () => {
                return isEdit
                    ? menuApi.updatePermission(payload)
                    : menuApi.createPermission(payload);
            },
            (data, resp) => {
                callback(resp.message);
            },
            {
                onFinally: () => {
                    submitLoading.value = false;
                },
            },
        );
    }

    /** 提交 */
    async function onSubmit(isEdit: boolean, callback: (message: string) => void): Promise<void> {
        if (!(await formRef.value?.validate())) return;
        submitLoading.value = true;
        if (menuType.value === "button") {
            submitPermission(isEdit, callback);
        } else {
            submitMenu(isEdit, callback);
        }
    }

    return {
        getInitFormMeta,
        getInitFormData,
        formData,
        resetForm,
        formRef,
        submitLoading,
        menuType,
        onSubmit,
    };
}
